package com.daily.pump.http;

import android.os.Handler;
import android.os.Message;

import com.daily.pump.utils.ExecutorServiceHelp;
import com.xunxi.mimi.utils.LogUtil;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.Socket;

/**
 * Desc:wifi串口通信协议
 * <p>
 * Author: [李豫]
 * Date: 2020-09-01
 * Copyright: Copyright (c) 2010-2020
 * Company: @咪咕动漫
 * Updater:
 * Update Time:
 * Update Comments:
 */
public class WifiSocketClient {

    public static final int CONNECTED_SUCC = 0;
    public static final int SEND_RESPONSE = 1;
    public static final int RESPONSE_TIMEOUT = 2;
    public static final int CONNECTED_FAIL = 3;
    public static final int CONN_TIMEOUT = 10*1000;

    /**
     * 是否已连接连接
     */
    private boolean isConnected;

    private Socket mSocket;
    private String mHostName;
    private int mPort;
    private boolean isConnecting;
    private OnMessageReceListener mOnMessageReceListener;

    public void setOnMessageReceListener(OnMessageReceListener listener) {
        this.mOnMessageReceListener = listener;
    }

    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (msg.what == SEND_RESPONSE) {
                String response = (String) msg.obj;
                if (mOnMessageReceListener != null) {
                    mOnMessageReceListener.onMessageRece(SEND_RESPONSE, response);
                }
                LogUtil.error(WifiSocketClient.class, "response:" + response);
            } else if (msg.what == CONNECTED_SUCC) {
                if (mOnMessageReceListener != null) {
                    mOnMessageReceListener.onMessageRece(CONNECTED_SUCC, "");
                }
                LogUtil.error(WifiSocketClient.class, "connected succ");
            } else if (msg.what == RESPONSE_TIMEOUT) {
                if (mOnMessageReceListener != null) {
                    mOnMessageReceListener.onMessageRece(RESPONSE_TIMEOUT, "");
                }
                LogUtil.error(WifiSocketClient.class, "response_timeout:");
            }
        }
    };

    public WifiSocketClient() {
    }

    /**
     * Desc:连接socket
     * <p>
     * Author: [李豫]
     * Date: 2020-09-01
     *
     * @param hostName
     * @param port
     */
    public void connect(String hostName, int port) {
        this.mHostName = hostName;
        this.mPort = port;
        this.isConnecting = true;
        initClientSocket(hostName, port);
        ReadThread readThread = new ReadThread();
        readThread.start();
        beginConnCountDown();
    }

    private void beginConnCountDown() {
        mHandler.removeCallbacks(connRunnable);
        mHandler.postDelayed(connRunnable, CONN_TIMEOUT);
    }

    /**
     * Desc:发送消息
     * <p>
     * Author: [李豫]
     * Date: 2020-09-01
     *
     * @param data
     */
    public void TCPSend(final String data) {
        LogUtil.error(WifiSocketClient.class, "TCPSend:" + data);
        if (mSocket == null || mSocket.isClosed()) {
            initClientSocket(mHostName, mPort);
            return;
        }
        // 开启线程来发起网络请求
        ExecutorServiceHelp.executeDisplay(new Runnable() {
            @Override
            public void run() {
                try {
                    PrintWriter writer = new PrintWriter(mSocket.getOutputStream());
//                    byte[] sendData = data.getBytes(Charset.forName("ASCII"));
                    LogUtil.error(WifiSocketClient.class, "TCPSend:" + data);
                    writer.write(data, 0, data.length());

                    writer.flush();
                } catch (IOException ex) {
                    ex.printStackTrace();
                    Message message = new Message();
                    message.what = RESPONSE_TIMEOUT;
                    // 将服务器返回的结果存放到Message中
                    message.obj = "操作失败！";
                    mHandler.sendMessage(message);
                }
            }
        });
    }

    private void initClientSocket(String hostName, int port) {
        ExecutorServiceHelp.executeDisplay(new Runnable() {
            @Override
            public void run() {
                try {
                    onRelease();
                    if (mSocket == null) {
                        mSocket = new Socket();
                        mSocket.setKeepAlive(true);
                    }
                    if (mSocket != null){
                        if (!mSocket.isConnected()) {
                            mSocket.connect(new InetSocketAddress(hostName, port), 4000);
                            Message message = new Message();
                            message.what = CONNECTED_SUCC;
                            mHandler.sendMessage(message);
                            isConnected = true;
                        } else {
                            Message message = new Message();
                            message.what = CONNECTED_SUCC;
                            mHandler.sendMessage(message);
                            isConnected = true;
                        }
                        isConnecting = false;
                    }
                } catch (IOException ex) {
                     ex.printStackTrace();
                    if (!isConnecting){
                        //超时就不再继续重连
                        Message message = new Message();
                        message.what = RESPONSE_TIMEOUT;
                        mHandler.sendMessage(message);
                    }else {
                        mSocket = null;
                        isConnected = false;
                        reconnect();
                    }

                }
            }
        });
    }

    private Runnable connRunnable = new Runnable() {
        @Override
        public void run() {
            isConnecting = false;
        }
    };

    private void reconnect() {
        initClientSocket(mHostName, mPort);
    }

    private class ReadThread extends Thread {

        @Override
        public void run() {
            super.run();
            while (true) {
                byte[] data = receiveData();
                if (data != null) {
                    // 将服务器返回的结果存放到Message中
                    if (data.length > 1){
                        try {
                            Message message = new Message();
                            message.what = SEND_RESPONSE;
                            message.obj = new String(data, "UTF-8");
                            mHandler.sendMessage(message);
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * Desc:处理接收数据
     * <p>
     * Author: [李豫]
     * Date: 2020-09-01
     *
     * @return byte [ ]
     */
    public byte[] receiveData() {
        byte[] data = null;
        if (mSocket != null && mSocket.isConnected()) {
            try {
                BufferedInputStream bufferedInputStream = new BufferedInputStream(mSocket.getInputStream());
                data = new byte[bufferedInputStream.available()];
                bufferedInputStream.read(data);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            data = new byte[1];
        }
        return data;
    }

    public void onRelease() {
        try {
            if (mSocket != null) {
                mSocket.close();
            }
            mSocket = null;
            isConnected = false;
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public interface OnMessageReceListener {
        void onMessageRece(int code, String message);
    }
}
